﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SuperSocket.SocketBase.Protocol;
using SuperSocket.SocketBase;
using LogLib;
using PrintingServer.ServerBase;
using IPrinting;
using PhotoProcess;
using ComLib.ComFun;

namespace PrintingServer
{
    /// <summary>
    ///  代表监听客户端连接，承载TCP连接的服务器实例。
    ///  理想情况下，我们可以通过AppServer实例获取任何你想要的客户端连接，
    ///  服务器级别的操作和逻辑应该定义在此类之中。       
    /// </summary>
    public class PhotoPrintingServer : AppServer<ClientRequestPackSession, BinaryRequestInfo>, IServer
    {
        protected string _error = "";
        public string ErrorMessage
        {
            get
            {
                return _error;
            }
        }

        /// <summary>
        /// 指示服务器是否已经启动
        /// </summary>
        public bool Running
        {
            get { return this.State == ServerState.Running; }
        }

        // 用于将原图处理成目标图片的PXL操作对象
        private PhotoPreprocess _pxlProcess = null;
        public PhotoPreprocess PxlProcess
        {
            get { return _pxlProcess; }
        }

        public Dictionary<string, IPhotoPrint> PrintApps
        {
            get;
            set;
        }

        /// <summary>
        /// 当前活动的会话
        /// </summary>
        public ClientRequestPackSession ActivedSession
        {
            get;
            set;
        }

        /// <summary>
        /// 启动或登录失败的接口列表
        /// </summary>
        private List<KeyValuePair<string, string>> listInitFailedInterfaces = new List<KeyValuePair<string, string>>();

        /// <summary>
        /// 存储session和对应ip端口号的泛型集合
        /// </summary>
        public Dictionary<string, ClientRequestPackSession> SessionList = new Dictionary<string, ClientRequestPackSession>();

        public event PrintResponsedEventHandler PrintResponsed;
        public void ReportPrintingReponse(PrintResponsePackge packge)
        {
            if (PrintResponsed != null)
            {
                PrintResponsed(this, new PrintResponsedEventArgs(packge));
            }
        }

        public event PrintTimeoutEventHandler PrintTimeout;
        public void OnPrintTimeout(string message)
        {
            if (PrintTimeout != null)
            {
                PrintTimeout(this, new PrintTimeoutEventArgs(message));
            }
        }

        public event Action AppExited;
        public void OnAppExited(string inParams)
        {
            if (AppExited != null)
            {
                AppExited();
            }
        }

        private LocalServerConfig _config = new LocalServerConfig();

        public PhotoPrintingServer()
            : base(new ClientRequestPackReceiveFilterFactory())
        {
            _pxlProcess = new PhotoPreprocess();
        }

        public event NewSessionRequestReceivedHandler NewSessionRequestReceived;
        public void OnNewSessionRequestReceived(ClientRequestPackSession session, PrintDataPackge pack)
        {
            ActivedSession = session;
            if (NewSessionRequestReceived != null)
            {
                NewSessionRequestReceived(session, pack);
            }
        }

        public bool Init()
        {
            var config = new SuperSocket.SocketBase.Config.ServerConfig()
            {
                Name = _config.Name,
                ServerTypeName = _config.Name,
                ClearIdleSession = _config.ClearIdleSession, // 300秒执行一次清理300秒没数据传送的连接
                ClearIdleSessionInterval = _config.ClearIdleSessionInterval,
                IdleSessionTimeOut = _config.IdleSessionTimeOut,
                MaxRequestLength = _config.MaxRequestLength, //最大包长度
                Ip = _config.Ip,
                Port = _config.Port,
                MaxConnectionNumber = _config.MaxConnectionNumber,
            };
            if (this.State == ServerState.NotInitialized)
            {
                if (!Setup(config))
                {
                    _error = "Failed to Setup";
                    return false;
                }
                else
                {
                    string info = string.Format("{0}初始化成功，IP:{1}, port:{2}", config.Name, config.Ip, config.Port);
                    Log.WriteAsync(info);
                }
            }
            if (!_pxlProcess.Init())
            {
                _error = _pxlProcess.ErrorMessage;
                return false;
            }
            return true;
        }

        public bool StartServer()
        {
            if (this.State == ServerState.NotStarted)
            {
                if (Start())
                {
                    Log.WriteAsync("服务已启动");
                    return true;
                }
                else
                {
                    _error = "Failed to Start";
                }
            }
            return true;
        }

        public void Close()
        {
            if (this.Running)
            {
                Stop();                           
            }
            if (_pxlProcess.Inited)
            {
                _pxlProcess.Exit(); 
            }
            Dispose();           
        }

        /// <summary>
        /// 接收数据
        /// </summary>
        /// <param name="session"></param>
        /// <param name="requestInfo"></param>
        public void appServer_NewRequestReceived(ClientRequestPackSession session, BinaryRequestInfo requestInfo)
        {         
            //ActivedSession = session;
            //session.Charset = Encoding.UTF8;
            //ipAddress_Receive = session.RemoteEndPoint.ToString();
            //SetMessage("收到" + ipAddress_Receive + "数据: " + requestInfo.Key + " " + requestInfo.Body);
        }

        public void InitInterfaces(string inParamString)
        {
            listInitFailedInterfaces.Clear();
            foreach (KeyValuePair<string, IPhotoPrint> p in PrintApps)
            {             
                string outParams = "";
                IPhotoPrint printApp = p.Value;
                printApp.Init(inParamString, out outParams);
                if (!printApp.Inited)
                {
                    string info = string.Format("{0}初始化失败: {1}", printApp.Name, printApp.ErrorMessage);
                    Log.WriteAsync(info);
                    listInitFailedInterfaces.Add(new KeyValuePair<string, string>(printApp.Name, printApp.ErrorMessage));
                    OnInitFailed(printApp, printApp.ErrorMessage, "");
                }
                else
                {
                    OnInitOK(printApp, "");
                }
            }
        }

        protected void OnInitOK(IPhotoPrint printApp, string outParams = "")
        {
            PrintResponsePackge pack = new PrintResponsePackge(printApp.Name, PrintAction.Init);
            pack.Success = true;
            pack.Result = PrintResult.InitOK;
            pack.Message = "";
            pack.SetParams(outParams);
            ReportPrintingReponse(pack);
        }

        protected void OnInitFailed(IPhotoPrint printApp, string reasonMsg, string outParams)
        {
            PrintResponsePackge pack = new PrintResponsePackge(printApp.Name, PrintAction.Init);
            pack.Success = false;
            pack.Result = PrintResult.InitFailed;
            pack.Message = reasonMsg;
            pack.SetParams(outParams);
            ReportPrintingReponse(pack);
        }

        /// <summary>
        /// 检查初始化结果
        /// </summary>
        /// <returns></returns>
        public bool CheckInitResult(out string msg)
        {
            msg = "";
            if (listInitFailedInterfaces.Count > 0)
            {
                StringBuilder builder = new StringBuilder();
                for (int i = 0; i < listInitFailedInterfaces.Count; i++)
                {
                    builder.Append(listInitFailedInterfaces[i].Key);
                    builder.Append(":");
                    builder.Append(listInitFailedInterfaces[i].Value);
                }
                msg = builder.ToString();
                return false;
            }
            else
            {
                return true;
            }
        }

        public void ReleaseInterfaces(string inParamString)
        {
            foreach (KeyValuePair<string, IPhotoPrint> p in PrintApps)
            {
                IPhotoPrint printApp = p.Value;
                if (printApp != null && printApp.Inited)
                {
                    printApp.Exit();
                }              
            }
        }

        /// <summary>
        /// 当观测超时
        /// </summary>
        /// <param name="action"></param>
        /// <param name="msg"></param>
        public void OnWatchTimeout(ClientRequestPackSession session, IPhotoPrint printApp, string action, string msg)
        {
            PrintResponsePackge pack = new PrintResponsePackge(printApp.Name, action);
            pack.Success = false;
            pack.Message = msg;
            pack.Result = PrintResult.Timeout;
            ReportPrintingReponse(pack);
            if (session.Connected)
            {
                session.Send(pack);
            }      
        }

        public void OnCatchException(ClientRequestPackSession session, IPhotoPrint printApp, string action, Exception ex)
        {
            PrintResponsePackge pack = new PrintResponsePackge(printApp.Name, action);
            pack.Success = false;
            pack.Message = ex.Message;
            pack.Result = PrintResult.CatchException;
            pack.SetParams("");
            ReportPrintingReponse(pack);
            if (session.Connected)
            {
                session.Send(pack);
            }            
        }

        public void SendPackage(PrintResponsePackge pack)
        {
            if (ActivedSession != null && ActivedSession.Connected)
            {
                ActivedSession.Send(pack);
            }
        }
    }
}
